﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Reflection;

namespace Utility.Inspector.ReorderableList
{
	public class ListDrawer<TItem> : GenericListAdaptor<TItem>
	{
		public ListDrawer (IList<TItem> list, ReorderableListControl.ItemDrawer<TItem> itemDrawer, float itemHeight) : base (list, itemDrawer, itemHeight)
		{
			OnListChanged ();
		}

		public ListDrawer () : base ()
		{
			OnListChanged ();
		}

		public ListDrawer (IList<TItem> list) : base (list)
		{
			OnListChanged ();
		}

		protected virtual float LineHeight => ReorderableListGUI.DefaultItemHeight;

		protected virtual ReorderableListFlags ListFlags => 0;

		protected virtual TItem CreateItem ()
		{
			Type type = typeof (TItem);
			if (type.IsClass)
			{
				var ctor = type.GetConstructor (Type.EmptyTypes);
				if (ctor != null)
				{
					return (TItem)ctor.Invoke (null);
				}
			}
			return default;
		}

		protected virtual void OnListChanged ()
		{

		}

		public override float GetItemHeight (int index)
		{
			return LineHeight;
		}

		public virtual float GetTotalHeight ()
		{
			var sum = 0f;
			for (int i = 0; i < Count; i++)
			{
				sum += GetItemHeight (i);
			}
			return sum;
		}
		#region override
		public override void Add ()
		{
			List.Add (CreateItem ());
			OnListChanged ();
		}

		public override void Clear ()
		{
			base.Clear ();
			OnListChanged ();
		}

		public override void Duplicate (int index)
		{
			base.Duplicate (index);
			OnListChanged ();
		}

		public override void Insert (int index)
		{
			List.Add (CreateItem ());
			OnListChanged ();
		}

		public override void Move (int sourceIndex, int destIndex)
		{
			base.Move (sourceIndex, destIndex);
			OnListChanged ();
		}

		public override void Remove (int index)
		{
			base.Remove (index);
			OnListChanged ();
		}
		#endregion

		public void Draw ()
		{
			Draw (ListFlags);
		}

		public void Draw (ReorderableListFlags listFlags = 0)
		{
			ReorderableListGUI.ListField (this, listFlags);
		}

		public void Draw (IList<TItem> list)
		{
			Draw (list, ListFlags);
		}

		public void Draw (IList<TItem> list, ReorderableListFlags listFlags)
		{
			if (list != List)
			{
				List = list;
				OnListChanged ();
			}
			ReorderableListGUI.ListField (this, listFlags);
		}

		public void Draw (Rect rect, IList<TItem> list)
		{
			Draw (rect, list, ListFlags);
		}
		
		public void Draw (Rect rect, IList<TItem> list, ReorderableListFlags listFlags)
		{
			if (list != List)
			{
				List = list;
				OnListChanged ();
			}
			ReorderableListGUI.ListFieldAbsolute (rect,this, listFlags);
		}
	}

	public class ListDrawer<TItem, TData> : ListDrawer<TItem>
	{
		protected List<TData> itemDataList = new List<TData> ();

		public ListDrawer (IList<TItem> list, ReorderableListControl.ItemDrawer<TItem> itemDrawer, float itemHeight) : base (list, itemDrawer, itemHeight)
		{
		}

		public ListDrawer () : base ()
		{
		}

		public ListDrawer (IList<TItem> list) : base (list)
		{
		}

		protected virtual void RefreshData ()
		{
			itemDataList.Clear ();
			for (int i = 0; i < List.Count; i++)
			{
				itemDataList.Add (CreateData (i));
			}
		}

		protected virtual TData CreateData (int index)
		{
			return default;
		}

		protected override void OnListChanged ()
		{
			base.OnListChanged ();
			RefreshData ();
		}

		public override void DrawItem (Rect position, int index)
		{
			TData data = itemDataList[index];
			DrawItem (position, index, data);
			itemDataList[index] = data;
		}

		protected virtual TData DrawItem (Rect position, int index, TData data)
		{
			return default;
		}
	}

}